#pragma once

#include "actorproperty.h"
#include "templateclass.h"
#include <osg\ref_ptr>
#include "vrdatacore_global.h"

namespace VrDataCore
{
	template <typename T,typename R>
	class VRDATACORE_EXPORT GenericProperty : public CoreBase::ActorProperty
	{
	public:
		typedef osg::ref_ptr<FuncBase> PropertyFun;
		typedef void (T::*SetFun)(R);
		typedef R (T::*GetFun)();
		GenericProperty(const QString& datatype,const QString& name,
			const std::string& label,T* obj,SetFun set, GetFun get,
			const QString& isshowgui,const QString& bindingguitype,
			bool readOnly = false) : CoreBase::ActorProperty(datatype, name,label,isshowgui, bindingguitype, readOnly)
		{
			_getPropFunctor = new VoidFunc<R,T>(get,obj);
			_setPropFunctor = new Type_1Func<void,T,R>(set,obj);
		}

		virtual void copyFrom(const CoreBase::ActorProperty& otherProp)
		{
			if (getDataType() != otherProp.getDataType())
			{
				return;
			}
			const GenericProperty<T,R>& prop =
				static_cast<const GenericProperty<T,R>&>(otherProp);
			setValue(prop.getValue());
		}

		void setValue(R value)
		{
			if(!isReadOnly())
			{
				PramBase* pram = new Parm1<R>(value);
				_setPropFunctor->callFunc(pram);
			}
		}

		R getValue() const 
		{
			return dynamic_cast<VoidFunc<R,T>*>(_getPropFunctor.get())->callReturnFunc(); 
		}

		virtual const QString toQString() const {return "";}
		virtual bool fromString(const QString& value)
		{
			return false;
		}
	protected:
		virtual ~GenericProperty() { }
	private:
		PropertyFun _getPropFunctor;
		PropertyFun _setPropFunctor;
	};
}